package gen.tools.deploy;

import gen.tools.Widgets;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.as.cli.CommandContext;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.dmr.ModelNode;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class DepMemphis extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public DepMemphis() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		final Widgets wid = new Widgets();
		response.setCharacterEncoding(wid.UIcodeSet);
		response.setContentType("application/text");

		final long depId = Long.parseLong(request.getParameter("depId"));
		final String empId = request.getParameter("empId");
		final String apURL = request.getParameter("apURL");
		final String apUSR = request.getParameter("apUSR");
		final char[] apPWD = request.getParameter("apPWD").toCharArray();
		final int apPORT = Integer.parseInt(request.getParameter("apPORT"));
		final String squadId = request.getParameter("squadId");
		final String fileName = request.getParameter("fileName");
		final String relativePath = "根目錄".equalsIgnoreCase(request
				.getParameter("relativePath")) ? ""+fileName : request
				.getParameter("relativePath");
		
		final long fileVer = Long.parseLong(request.getParameter("fileVer"));
		final String svnURL = request.getParameter("svnURL");
		final String svnUSR = request.getParameter("svnUSR");
		final String svnPWD = request.getParameter("svnPWD");
		final boolean isExist = Boolean.valueOf(request.getParameter("isExist")); // 此檔案，是否仍存在於Domain中
		final ByteArrayOutputStream baos = new ByteArrayOutputStream();
		SVNRepository repo = null;
		final ISVNAuthenticationManager authManager = SVNWCUtil
				.createDefaultAuthenticationManager(svnUSR, svnPWD);
		InputStream inputStream = null;
		OutputStream outputStream = null;
		CommandContext cmdCtx = null;
		ModelNode result = null;
		String res = "";
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		boolean isMasterDataOK = false;	//若發生錯誤時，要留下錯誤訊息，以此判斷是要從單頭開始寫，還是單身

		try {
			//取得部署記錄的ID
			int depMemphisSN = wid.getDepSN(depId);
			
			conn= wid.getConn();
			//表示目前還未創建，開始創建
			if ( depMemphisSN==-1 ) {	
				String strSQL = "INSERT INTO depmemphis (svnUSR,svnURL,depMemphisId,cDT,creatorId) VALUES (?,?,?,?,?)";
				ps = conn.prepareStatement(strSQL);
				ps.setString(1, svnUSR);
				ps.setString(2, svnURL);
				ps.setLong(3, depId);
				ps.setTimestamp(4, wid.cDT());
				ps.setString(5, empId);
				ps.execute();
				depMemphisSN = wid.getDepSN(depId);
			}
			isMasterDataOK = true;
			
			repo = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(svnURL));
			repo.setAuthenticationManager(authManager);
			repo.getFile(relativePath, fileVer, new SVNProperties(), baos);
			
			// read this file into InputStream
			inputStream = new ByteArrayInputStream(baos.toByteArray() );
	 
			// write the inputStream to a FileOutputStream
			outputStream = new FileOutputStream(new File(fileName));
	 
			int read = 0;
			byte[] bytes = new byte[1024];
	 
			while ((read = inputStream.read(bytes)) != -1) {
				outputStream.write(bytes, 0, read);
			}

			String commandLine = "deploy " + fileName + " --server-groups=" + squadId;
			if (isExist) {
				commandLine = "deploy --name=" + fileName + " --server-groups=" + squadId;
			}

			cmdCtx = wid.initCommandContext(apURL, apPORT, apUSR, apPWD);
			
			ModelControllerClient client = cmdCtx.getModelControllerClient();
			if (cmdCtx.getExitCode() == 0 && !cmdCtx.isTerminated()) {
				final ModelNode requestNode = cmdCtx.buildRequest(commandLine);
				result = client.execute(requestNode);
				res = result.get("outcome").toString().substring(1, result.get("outcome").toString().length()-1);
			}
			String isSuccess = "success".equalsIgnoreCase(res)?"t":"f";
			String strSQL = "INSERT INTO depmemphisdetail (depMemphisSN,depMemphisDetailId,squadId,fileName,fileVer,relativePath,isSuccess,errMsg,isAssume,isDep) VALUES (?,?,?,?,?,?,?,?,?,?)";
			//表示目前還未創建，開始創建
			ps = conn.prepareStatement(strSQL);
			ps.setInt(1, depMemphisSN);
			ps.setInt(2, wid.getLatestDepMemphisDetailId(depMemphisSN));
			ps.setString(3,squadId);
			ps.setString(4,fileName);
			ps.setLong(5,fileVer);
			ps.setString(6,relativePath);
			ps.setString(7,isSuccess);
			ps.setString(8,result.toString());
			ps.setString(9,"f");	//是否為理論值
			ps.setString(10,"t");	//是否為部署
			ps.execute();
			
		} catch (Exception e) {
			wid.errLog(e);
			res = e.toString();
			int depMemphisSN=0;
			if( !isMasterDataOK ) {
				String strSQL = "INSERT INTO depmemphis (svnUSR,svnURL,depMemphisId,cDT,creatorId) VALUES (?,?,?,?,?)";
				try {
					if (conn==null ) {
						System.out.println("DepMemphis的Catch中，連結為空");
						conn = wid.getConn();
					} else {
						System.out.println("DepMemphis的Catch中，連結非空");
					}
					
					ps = conn.prepareStatement(strSQL);
					ps.setString(1, svnUSR);
					ps.setString(2, svnURL);
					ps.setLong(3, depId);
					ps.setTimestamp(4, wid.cDT());
					ps.setString(5, empId);
					ps.execute();
					depMemphisSN = wid.getDepSN(depId);
				} catch (Exception e1) {
					wid.errLog(e1);
				}
			}
			String strSQL = "INSERT INTO depmemphisdetail (depMemphisSN,depMemphisDetailId,squadId,fileName,fileVer,relativePath,isSuccess,errMsg,isAssume,isDep) VALUES (?,?,?,?,?,?,?,?,?,?)";
			try {
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, depMemphisSN);
				ps.setInt(2, wid.getLatestDepMemphisDetailId(depMemphisSN));
				ps.setString(3,squadId);
				ps.setString(4,fileName);
				ps.setLong(5,fileVer);
				ps.setString(6,"");			
				ps.setString(7,"f");		//是否執行成功
				ps.setString(8,wid.errProcess(e));
				ps.setString(9, "f");		//是否為理論值
				ps.setString(10, "t");		//是否為部署
				ps.execute();
			} catch (Exception e1) {
				wid.errLog(e1);
			}
		} finally {
			try {
				if ( rs !=null ) {rs.close();}
				if ( ps !=null ) {ps.close();}
				if ( conn !=null ) {conn.close();}
			} catch (SQLException e) {e.printStackTrace();}
			if (repo != null) { repo.closeSession();}
			if (cmdCtx != null) {cmdCtx.terminateSession();}
			if (baos != null) {baos.close();}
			if (inputStream != null) {inputStream.close();}
			if (outputStream != null) {outputStream.close();}
		}

		response.getWriter().write(res);
	}

}
